﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Threading;
using System.Globalization;
using TheOutLetLibrary.Infraestrutura;
using System.Data.OleDb;

namespace TheOutLetLibrary.Dominio {

    public class Carregadork_product {

        private IFactoryDAO factoryDAO;
        private k_product product;
        private XNamespace ad = "http://kanlo.com.br/product";

        public Carregadork_product(IFactoryDAO factoryDAO) {
            this.factoryDAO = factoryDAO;
        }

        public k_productLog CarregueProduct(XElement productXml) {

            string statusDaCarga = "Carga efetuada com sucesso";
            product = new k_product();

            try {

                Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
                Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");

                product.Id = Int32.Parse(productXml.Element(ad + "id").Value);
                product.ExternalId = productXml.Element(ad + "externalId").Value;
                product.ProductName = productXml.Element(ad + "name").Value;
                product.DateCreated = DateTime.Parse(productXml.Element(ad + "dateCreated").Value);
                product.LastUpdated = DateTime.Parse(productXml.Element(ad + "lastUpdated").Value);
                product.ShortName = productXml.Element(ad + "shortName").Value;
                product.SalePrice = Decimal.Parse(productXml.Element(ad + "price").Element(ad + "salePrice").Value);
                product.DefaultPrice = Decimal.Parse(productXml.Element(ad + "price").Element(ad + "defaultPrice").Value);
                product.InventoryTracking = bool.Parse(productXml.Element(ad + "inventoryTracking").Value);
                product.Saleable = bool.Parse(productXml.Element(ad + "saleable").Value);
                product.Hidden = bool.Parse(productXml.Element(ad + "hidden").Value);
                product.VariationMultiplicity = productXml.Element(ad + "variationMultiplicity").Value;
                product.IsKit = bool.Parse(productXml.Element(ad + "isKit").Value);

                product.Category = new k_category {
                    Id = Int32.Parse(productXml.Element(ad + "category").Attribute("id").Value),
                    CategoryName = productXml.Element(ad + "category").Element(ad + "name").Value,
                    Link = productXml.Element(ad + "category").Element(ad + "link").Value
                };

                product.Brand = new k_brand {
                    Id = Int32.Parse(productXml.Element(ad + "brand").Attribute("id").Value),
                    BrandName = productXml.Element(ad + "brand").Element(ad + "name").Value,
                    Link = productXml.Element(ad + "brand").Element(ad + "link").Value
                };

                IEnumerable<XElement> images = from image in productXml.Descendants(ad + "images").Descendants(ad + "image")
                                               select image;

                foreach(XElement image in images) {
                    product.Images.Add(new k_image {
                        Link = image.Element(ad + "link").Value,
                        ImageName = image.Element(ad + "name").Value,
                        Type = image.Element(ad + "type").Value,
                        ProductId = product.Id
                    });
                }

                IEnumerable<XElement> skus = from sku in productXml.Descendants(ad + "skus").Descendants(ad + "sku")
                                             select sku;

                foreach(XElement sku in skus) {
                    product.Skus.Add(new k_sku {
                        Id = Int32.Parse(sku.Element(ad + "id").Value),
                        Variation = sku.Element(ad + "variation").Value,
                        Depth = Decimal.Parse(sku.Element(ad + "dimension").Element(ad + "depth").Value),
                        Height = Decimal.Parse(sku.Element(ad + "dimension").Element(ad + "height").Value),
                        Weight = Decimal.Parse(sku.Element(ad + "dimension").Element(ad + "weight").Value),
                        Width = Decimal.Parse(sku.Element(ad + "dimension").Element(ad + "width").Value),
                        ProductId = product.Id
                    });

                }

                Thread.CurrentThread.CurrentCulture = new CultureInfo("pt-BR");
                Thread.CurrentThread.CurrentUICulture = new CultureInfo("pt-BR");

                SalveContextoProduct();

            } catch (Exception ex) {
                statusDaCarga = ex.Message;
            }

            return new k_productLog {
                Product = product,
                StatusDaCarga = statusDaCarga
            };

        }

        private void SalveContextoProduct() {

            using(OleDbConnection conexao = factoryDAO.GetConexao) {

                OleDbTransaction transacao = null;

                try {

                    conexao.Open();
                    transacao = conexao.BeginTransaction();

                    IGenericDAO<k_category> categoryDAO = factoryDAO.Getk_categoryDAO(transacao);
                    if(categoryDAO.Ache(product.Category.Id) == null)
                        categoryDAO.Inclua(product.Category);

                    IGenericDAO<k_brand> brandDAO = factoryDAO.Getk_brandDAO(transacao);
                    if(brandDAO.Ache(product.Brand.Id) == null)
                        brandDAO.Inclua(product.Brand);

                    IGenericDAO<k_product> productDAO = factoryDAO.Getk_productDAO(transacao);
                    if(productDAO.Ache(product.Id) == null) {
                        productDAO.Inclua(product);
                        IGenericDAO<k_image> imageDAO = factoryDAO.Getk_imageDAO(transacao);
                        foreach(k_image image in product.Images)
                            imageDAO.Inclua(image);
                        IGenericDAO<k_sku> skuDAO = factoryDAO.Getk_skuDAO(transacao);
                        foreach(k_sku sku in product.Skus)
                            skuDAO.Inclua(sku);
                    } else {
                        // todo PAULO : implementar a rotina de alteração
                    }

                    transacao.Commit();

                } catch {
                    transacao.Rollback();
                    throw;
                }
            }
        }

        public IEnumerable<XElement> CarregueListaDeProducts(int offset) {
            string address = String.Format("product?offset={0}&max=100", offset);
            XElement produtos = APIKanlo.CarregaXml(address);
            return produtos.Descendants(ad + "product").Select(p => p);
        }

    }
}
